package cn.iocoder.yudao.module.brain.common;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Map;

/**
 * java模拟HTTP请求工具
 *
 * @author 99013
 * @ClassName HttpRequestUtil
 * @Description TODO
 * 作者：99013
 * 创建时间：2020年12月03日 14:07:35
 * @Version 2.0
 **/
public class HttpRequestUtil {
    private static final Logger log = LoggerFactory.getLogger(HttpRequestUtil.class);
    /**
     * POST请求
     */
    private static final String POST = "POST";
    /**
     * PUT请求
     */
    private static final String PUT = "PUT";
    /**
     * GET请求
     */
    private static final String GET = "GET";
    /**
     * DELETE请求
     */
    private static final String DELETE = "DELETE";
    /**
     * utf-8
     */
    public static final String CHARSET_UTF8 = "UTF-8";
    /**
     * 请求内容类型
     */
    public static final String CONTENT_TYPE = "Content-type";
    /**
     * 请求通用格式
     */
    public static final String CONTENT_TYPE_JSON = "application/json";
    /**
     * multipart/form-data类型
     */
    public static final String CONTENT_TYPE_FORMDATA = "multipart/form-data";
    /**
     * text/plain类型
     */
    public static final String CONTENT_TYPE_TEXT_PLAIN = "text/plain";
    /**
     * image/jpeg类型
     */
    public static final String MIME_TYPE_IMAGE_JPEG = "image/jpeg";
    /**
     * 边界
     */
    private static final String BOUNDARY = "----WebKitFormBoundary07I8UIuBx6LN2KyY";


    /**
     * Get请求
     *
     * @param url       请求路径
     * @param params    请求参数
     * @param cookie    Cookie
     * @param headerMap 请求头补充参数
     * @return java.lang.String
     * <br><br><b>作者: 990130556 <a class=b href="https://blog.csdn.net/lingdu_dou">lingdu</a></b><br>
     * 创建时间: 2021年08月26日 18:46:43
     */
    public static String sendGet(String url, Map<String, Object> params, String cookie, Map<String, String> headerMap) {
        return send(GET, url, params, cookie, headerMap, null, null);
    }

    /**
     * Delete请求
     *
     * @param url       请求路径
     * @param params    请求参数
     * @param cookie    cookie
     * @param headerMap 请求头补充参数
     * @return java.lang.String
     * <br><br><b>作者: 990130556 <a class=b href="https://blog.csdn.net/lingdu_dou">lingdu</a></b><br>
     * 创建时间: 2021年08月26日 18:48:02
     */
    public static String sendDelete(String url, Map<String, Object> params, String cookie, Map<String, String> headerMap) {
        return send(DELETE, url, params, cookie, headerMap, null, null);
    }

    /**
     * Post请求
     *
     * @param url    第三方接口地址
     * @param params 请求参数
     * @return java.lang.String 返回信息
     * <br><br><b>作者: 990130556 <a class=b href="https://blog.csdn.net/lingdu_dou">lingdu</a></b><br>
     * 创建时间: 2020年12月03日 17:45:21
     */
    public static String sendPost(String url, Map<String, Object> params, String cookie, Map<String, String> headerMap) {
        return sendPostUplodFile(url, params, cookie, headerMap, null, null);
    }

    /**
     * 模拟http请求上传文件及相关参数
     *
     * @param url      第三方上传文件地址
     * @param fileName 文件名
     * @param params   请求参数
     * @param bytes    文件字节码
     * @param cookie   Cookie
     * @return java.lang.String
     */
    public static String sendPostUplodFile(String url, Map<String, Object> params, String cookie, Map<String, String> headerMap, String fileName, byte[] bytes) {
        return send(POST, url, params, cookie, headerMap, fileName, bytes);
    }

    /**
     * put请求方式
     *
     * @param url    请求路径
     * @param params 请求参数
     * @param cookie cookie
     * @return java.lang.String
     * 创建时间: 2021年03月07日 09:16:34
     */
    public static String sendPut(String url, Map<String, Object> params, String cookie, Map<String, String> headerMap) {
        return send(PUT, url, params, cookie, headerMap, null, null);
    }

    /**
     * put请求方式 上传文件
     *
     * @param url      请求路径
     * @param fileName 文件名
     * @param params   请求参数
     * @param bytes    文件字节码
     * @param cookie   cookie
     * @return java.lang.String
     * 创建时间: 2021年03月07日 09:16:34
     */
    public static String sendPutUplodFile(String url, Map<String, Object> params, String cookie, Map<String, String> headerMap, String fileName, byte[] bytes) {
        return send(PUT, url, params, cookie, headerMap, fileName, bytes);
    }


    /**
     * 执行请求
     *
     * @param type      请求类型
     * @param url       第三方请求地址
     * @param params    请求参数
     * @param cookie    Cookie
     * @param headerMap 补充请求头参数
     * @param fileName  文件名
     * @param bytes     文件字节码
     * @return java.lang.String
     * <br><br><b>作者: 990130556 <a class=b href="https://blog.csdn.net/lingdu_dou">lingdu</a></b><br>
     * 创建时间: 2021年08月26日 18:21:34
     */
    private static String send(String type, String url, Map<String, Object> params, String cookie, Map<String, String> headerMap, String fileName, byte[] bytes) {
        DataOutputStream out = null;
        BufferedReader in = null;
        StringBuilder result = new StringBuilder();
        try {
            // GET 和 DELETE 请求
            if (type.equals(GET) || type.equals(DELETE)) {
                if (params != null) {
                    StringBuilder urlBuilder = new StringBuilder(url + "?");
                    for (String s : params.keySet()) {// 防止中文乱码 ↓
                        urlBuilder.append(s).append("=").append(URLEncoder.encode(params.get(s).toString(), "utf-8")).append("&");
                    }
                    url = urlBuilder.toString();
                }
            }
            //打开和URL之间的连接
            HttpURLConnection conn = getHttpUrlConnection(url, type, cookie, headerMap);
            // POST 和 PUT 请求
            if (type.equals(POST) || type.equals(PUT)) {
                out = new DataOutputStream(conn.getOutputStream());
                byte[] end_data = ("\r\n--" + BOUNDARY + "--\r\n").getBytes();
                //添加参数
                if (params != null) {
                    for (String key : params.keySet()) {
                        String sb = "--" +
                                BOUNDARY +
                                "\r\n" +
                                "Content-Disposition: form-data;name=\"" + key + "\"" +
                                "\r\n" +
                                "\r\n" +
                                params.get(key) +
//								URLEncoder.encode(params.get(key).toString(), "utf-8")+
                                "\r\n";
                        out.write(sb.getBytes());
                    }
                }
                // 传文件
                if (null != fileName && null != bytes) {
                    //添加参数file
                    String sb = "--" +
                            BOUNDARY +
                            "\r\n" +
                            "Content-Disposition: form-data;name=\"file\";filename=\"" + fileName + "\"" +
                            "\r\n" +
                            "Content-Type: " + MIME_TYPE_IMAGE_JPEG +
                            "\r\n" +
                            "\r\n";
                    out.write(sb.getBytes());
                    // TODO 写文件
                    out.write(bytes);
                    out.write("\r\n".getBytes());
                }
                out.write(end_data);
                //flush输出流的缓冲
                out.flush();
            }
            //定义BufferedReader输入流来读取URL的响应
            in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                result.append(line);
            }
        } catch (Exception e) {
            log.error("发送请求出现异常:", e);
            e.printStackTrace();
        } finally {
            try {
                if (out != null) {
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
        return result.toString();
    }

    /**
     * 和URL之间建立连接
     *
     * @param url       请求路径
     * @param type      请求类型
     * @param cookie    cookie
     * @param headerMap 请求头补充参数
     * @return java.net.HttpURLConnection 返回连接信息
     * <br><br><b>作者: 990130556 <a class=b href="https://blog.csdn.net/lingdu_dou">lingdu</a></b><br>
     * 创建时间: 2021年09月02日 15:51:28
     */
    private static HttpURLConnection getHttpUrlConnection(String url, String type, String cookie, Map<String, String> headerMap) throws IOException {
        URL realUrl = new URL(url);
        //打开和URL之间的连接
        HttpURLConnection conn = (HttpURLConnection) realUrl.openConnection();
        if (POST.equals(type) || PUT.equals(type)) {
            //发送POST请求必须设置如下两行
            conn.setDoOutput(true);
            conn.setDoInput(true);
        }
        conn.setUseCaches(false);
        conn.setRequestMethod(type);
        conn.setRequestProperty("connection", "Keep-Alive");
        conn.setRequestProperty("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36");
        conn.setRequestProperty("Charsert", CHARSET_UTF8);
        if (cookie != null) {
            conn.setRequestProperty("Cookie", cookie);
        }
        conn.setRequestProperty(CONTENT_TYPE, CONTENT_TYPE_FORMDATA + "; boundary=" + BOUNDARY);
        //填充请求头
        if (headerMap != null && headerMap.keySet().size() != 0) {
            for (String s : headerMap.keySet()) {
                conn.setRequestProperty(s, headerMap.get(s));
            }
        }
        conn.connect();
        return conn;
    }
}



